package com.redis.bloom.filter.process;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.redis.bloom.filter.data.vo.req.OrderSearchReqVO;
import com.redis.bloom.filter.data.vo.resp.OrderSearchRespVO;
import com.redis.bloom.filter.enums.BloomFilterEnum;
import com.redis.bloom.filter.mapper.TbOrderMapper;
import com.redis.bloom.filter.mapstruct.TbOrderCopyMapper;
import com.redis.bloom.filter.model.TbOrder;
import com.redis.bloom.filter.utils.BloomFilterUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * 布隆过滤器 - 处理
 *
 * @author chen
 * @date 2024年02月02日 8:12
 */
@Service
@Slf4j
public class TbOrderProcess {
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public void order() {
        //下单校验
        checkParam();
        //下单操作
        String orderNo = orderHandle();
        //下单完成后处理(布隆过滤器应该在这里添加)
        afterOrderHandle(orderNo);
    }


    /**
     * @author chen
     * @description 下单后处理
     * @param orderNo 订单号
     * @date: 2024/3/3 9:42
     */
    private void afterOrderHandle(String orderNo) {
        //redisTemplate.opsForValue().setBit("test-key",10,true);
        //通过这种方式实现，需要自己使用hash算法计算对应位数组下标位置（不推荐）
        //推荐使用redisson开箱即用的RBloomFilter
        //加载到布隆过滤器
        BloomFilterUtils.addValueToBloom(BloomFilterEnum.TB_ORDER_BLOOM_FILTER.getBloomFilterName(),orderNo);
        log.info("#加载完毕#");
        //其他操作.....
    }

    /**
     * @author chen
     * @description 下单操作
     * @date: 2024/3/3 9:41
     * @return
     */
    private String orderHandle() {
        //下单操作，此处省略
        //......................
        String orderNo =  "tb" + IdUtil.getSnowflakeNextIdStr();
        TbOrder tbOrder = new TbOrder();
        tbOrder.setId(IdUtil.getSnowflakeNextId());
        tbOrder.setOrderNo(orderNo);
        tbOrder.setOrderTime(new Timestamp(new Date().getTime()));
        //测试代码写死下单人
        tbOrder.setOrderBy("chen");
        //下单成功保存到数据库
        tbOrderMapper.insert(tbOrder);

        return orderNo;
    }

    /**
     * @author chen
     * @description 下单参数校验
     * @date: 2024/3/3 9:41
     */
    private void checkParam() {
        // TODO: 2024/3/3
    }

    /**
     * @author chen
     * @description 订单查询
     * @param reqVO 请求入参
     * @date: 2024/3/3 9:59
     * @return com.redis.bloom.filter.data.vo.resp.OrderSearchRespVO
     */
    public OrderSearchRespVO orderSearch(OrderSearchReqVO reqVO) {
        String orderNo = reqVO.getOrderNo();
        if(!BloomFilterUtils.isContainsInBloom(BloomFilterEnum.TB_ORDER_BLOOM_FILTER.getBloomFilterName(),orderNo)){
            log.info("布隆过滤器不存在#则代表数据库一定不存在，则直接返回空，不进行数据库查询#orderNo={}",reqVO.getOrderNo());
            return null;
        }
        QueryWrapper<TbOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no",reqVO.getOrderNo());
        //查询数据库
        List<TbOrder> tbOrders = tbOrderMapper.selectList(queryWrapper);
        if(CollectionUtil.isEmpty(tbOrders)){
            return null;
        }
        TbOrder tbOrder = tbOrders.get(0);
        //使用MapStruct复制对象返回，不暴漏数据库对象给前端
        OrderSearchRespVO respVO = TbOrderCopyMapper.INSTANCE.createOrderSearchRespVO(tbOrder);
        return respVO;
    }
}
